/*
 * @Descripttion: 
 * @version: V1.0.0
 * @Author: Maverick
 * @Date: 2025-03-23 18:47:05
 * @LastEditors: Maverick
 * @LastEditTime: 2025-03-25 00:57:11
 */

 #include <iostream>
 #include <memory>
using namespace std;
 std::weak_ptr<int> gw;
  
 void observe()
 {
     std::cout << "【1】gw.use_count() == " << gw.use_count() << "; ";
     // we have to make a copy of shared pointer before usage:
     if (std::shared_ptr<int> spt = gw.lock())
         // use the copy
         std::cout << "【1】*spt == " << *spt <<"\t"<<"\n\t"<< "spt.use_count() == " <<
         spt.use_count()<< '\n';
     else
         std::cout << "【4】gw is expired\n";
 }
  
 int main()
 {
     {
         auto sp= std::make_shared<int>(1000);
         cout<<"【0】sp.use_count()="<<sp.use_count()<<endl;
         gw = sp;
         cout<<"【0】gw.use_count()="<<gw.use_count()<<endl;
  
         observe();
     }
     cout<<"【2】gw.use_count()="<<gw.use_count()<<endl;
     observe();
 }
//  【0】sp.use_count()=1
//  【0】gw.use_count()=1
//  【1】gw.use_count() == 1; 【1】*spt == 1000
//          spt.use_count() == 2
//  【2】gw.use_count()=0
//  【1】gw.use_count() == 0; 【4】gw is expired

#include <chrono>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>

using namespace std::chrono_literals;
using namespace std;

struct Base
{
    Base() { std::cout << "[0]Base::Base()\n"; }

    // Note: non-virtual destructor is OK here
    ~Base() { std::cout << "[0]Base::~Base()\n"; }
};

struct Derived : public Base
{
    Derived() { std::cout << "[1]Derived::Derived()\n"; }

    ~Derived() { std::cout << "[1]Derived::~Derived()\n"; }
};

void print(auto rem, std::shared_ptr<Base> const& sp)
{
    //p.use_count() 返回与共享对象关联的智能指针的数量==引用计数 1 
    std::cout << rem << "\nget() = " << sp.get()
        << ", use_count() = " << sp.use_count() << '\n';
}

void thr(std::shared_ptr<Base> p)
{
  std::this_thread::sleep_for(500ms);
   static std::mutex io_mutex;
   std::lock_guard<std::mutex> lk(io_mutex);
   print("[0][ALL] pointer in a thread:", p);
    std::shared_ptr<Base> lp = p; // thread-safe, even though the
    print("[1][ALL] pointer in a thread:", lp);
    auto now = std::chrono::system_clock::now();
    // 转换为时间戳（毫秒）
    auto timestamp = std::chrono::time_point_cast<std::chrono::milliseconds>(now).time_since_epoch().count();
    std::cout << "----->Timestamp: " << timestamp << std::endl;
    // shared use_count is incremented
    {
        cout<<"Thread id="<<std::this_thread::get_id()<<endl;
        print("Local pointer in a thread:", lp);
        cout<<endl;
    }
}

int main()
{
    std::shared_ptr<Base> p= std::make_shared<Derived>();

   // print("Created a shared Derived (as a pointer to Base)", p);
   // cout<<endl;
    //cout<<"p.use_count()="<<p.use_count()<<endl;//p.use_count() 1
    //thread{} 生成一个新线程,并在新线程中执行指定的函数,并返回一个std::thread对象
    //thread t1{thrfunction,args...} 生成一个新线程,并在新线程中执行指定的函数,并返回一个std::thread对象
    //t1.join()等待线程t1执行完毕
    std::thread t1{ thr, p }, t2{ thr, p }, t3{ thr, p };
    p.reset(); // release ownership from main p.use_count() 0
    //cout<<"p.use_count()="<<p.use_count()<<endl<<"\n";//p.use_count() 0

    //p.use_count() 0
  //  print("Shared ownership between 3 threads and released ownership from main:", p);
   // cout<<endl;
    //cout<<endl;


    t1.join();
    t2.join();
    t3.join();

    std::cout << "All threads completed, the last one deleted Derived.\n";
}
// [0]Base::Base()
// [1]Derived::Derived()
// [0][ALL] pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 3
// [1][ALL] pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 4
// ----->Timestamp: 1742834823846
// Thread id=140056070936128
// Local pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 4

// [0][ALL] pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 2
// [1][ALL] pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 3
// ----->Timestamp: 1742834823852
// Thread id=140056079328832
// Local pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 3

// [0][ALL] pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 1
// [1][ALL] pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 2
// ----->Timestamp: 1742834823858
// Thread id=140056087721536
// Local pointer in a thread:
// get() = 0x557e1460dec0, use_count() = 2

// [1]Derived::~Derived()
// [0]Base::~Base()
// All threads completed, the last one deleted Derived.

#include <cassert>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <locale>
#include <memory>
#include <stdexcept>
 
// helper class for runtime polymorphism demo below
struct B
{
    virtual ~B() = default;
 
    virtual void bar() { std::cout << "B::bar\n"; }
};
 
struct D : B
{
    D() { std::cout << "D::D\n"; }
    ~D() { std::cout << "D::~D\n"; }
 
    void bar() override { std::cout << "D::bar\n"; }
};
 
// a function consuming a unique_ptr can take it by value or by rvalue reference
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
    p->bar();
    return p;
}
 
// helper function for the custom deleter demo below
void close_file(std::FILE* fp)
{
    std::fclose(fp);
}
 
// unique_ptr-based linked list demo
struct List
{
    struct Node
    {
        int data;
        std::unique_ptr<Node> next;
    };
 
    std::unique_ptr<Node> head;
 
    ~List()
    {
        // destroy list nodes sequentially in a loop, the default destructor
        // would have invoked its “next”'s destructor recursively, which would
        // cause stack overflow for sufficiently large lists.
        while (head)
        {
            auto next = std::move(head->next);
            head = std::move(next);
        }
    }
 
    void push(int data)
    {
        head = std::unique_ptr<Node>(new Node{data, std::move(head)});
    }
};
 
int main()
{
    std::cout << "1) Unique ownership semantics demo\n";
    {
        // Create a (uniquely owned) resource
        std::unique_ptr<D> p = std::make_unique<D>();
 
        // Transfer ownership to “pass_through”,
        // which in turn transfers ownership back through the return value
        std::unique_ptr<D> q = pass_through(std::move(p));
 
        // “p” is now in a moved-from 'empty' state, equal to nullptr
        assert(!p);
    }
 
    std::cout << "\n" "2) Runtime polymorphism demo\n";
    {
        // Create a derived resource and point to it via base type
        std::unique_ptr<B> p = std::make_unique<D>();
 
        // Dynamic dispatch works as expected
        p->bar();
    }
 
    std::cout << "\n" "3) Custom deleter demo\n";
    std::ofstream("demo.txt") << 'x'; // prepare the file to read
    {
        using unique_file_t = std::unique_ptr<std::FILE, decltype(&close_file)>;
        unique_file_t fp(std::fopen("demo.txt", "r"), &close_file);
        if (fp)
            std::cout << char(std::fgetc(fp.get())) << '\n';
    } // “close_file()” called here (if “fp” is not null)
 
    std::cout << "\n" "4) Custom lambda expression deleter and exception safety demo\n";
    try
    {
        std::unique_ptr<D, void(*)(D*)> p(new D, [](D* ptr)
        {
            std::cout << "destroying from a custom deleter...\n";
            delete ptr;
        });
 
        throw std::runtime_error(""); // “p” would leak here if it were a plain pointer
    }
    catch (const std::exception&)
    {
        std::cout << "Caught exception\n";
    }
 
    std::cout << "\n" "5) Array form of unique_ptr demo\n";
    {
        std::unique_ptr<D[]> p(new D[3]);
    } // “D::~D()” is called 3 times
 
    std::cout << "\n" "6) Linked list demo\n";
    {
        List wall;
        const int enough{1'000'000};
        for (int beer = 0; beer != enough; ++beer)
            wall.push(beer);
 
        std::cout.imbue(std::locale("en_US.UTF-8"));
        std::cout << enough << " bottles of beer on the wall...\n";
    } // destroys all the beers
}

#include<iostream>
using namespace std;
//类的定义
//c++类的静态数据成员
class A
{
    int x,y;
    static int shared;
    public:
    A():x(0),y(0){}
    A(int a,int b):x(a),y(b){}
    void print()
    {
        cout<<"x="<<x<<" y="<<y<<" shared="<<shared<<endl;
    }
    //静态成员函数 只能访问静态成员
    static void set(int a)
    {
        shared=a;
    }
    void printshared()
    {
        cout<<"shared="<<shared<<endl;
    }
    void increment()
    {
        shared++;
    }
    //静态成员函数 只能访问静态成员
    static void incrementshared()
    {
        shared++;
    }
    static int getshared()
    {
        return shared;
    }

};
int A::shared=0;
int main()
{
    A a1,a2;
    a1.print();
    a2.print();
    a1.set(100);
    a1.printshared();
    a2.printshared();
    a1.increment();
    a1.printshared();
    cout<<a1.getshared()<<endl;
    cout<<a2.getshared()<<endl;
    cout<<A::getshared()<<endl;;
    return 0;
}

#include<iostream>
#include<cstring>
using namespace std;

class String
{
private:
    char* str;
public:
    //默认构造函数
    String() :str(new char[1]) {
        *str = '\0';
        cout << "String()" << endl;
    }
    //默认析构函数
    ~String()
    {
        cout << "~String()" << endl;
        if (str != nullptr)
        {
            delete[]str;
            str = nullptr;

        }
    }
    //构造函数
    String(const char* strsource)
    {
        cout << "String(const char *strsource)" << endl;
        if (strsource == nullptr)
        {
            str = new char[1];
            *str = '\0';
        }
        else
        {
            int length = strlen(strsource);
            str = new char[length + 1];
            strncpy(str, strsource, length + 1);
        }
    }
    //拷贝构造函数
    String(const String& other) noexcept
    {
        cout << "String(const String &other)" << endl;
        int length = strlen(other.str) + 1;
        str = new char[length];
        strncpy(str, other.str, length);

    }
    //赋值运算符重载
    String& operator=(const String& other)
    {
        cout << "String& operator=(cosnt String &other)" << endl;
        //对象地址相同
        if (this == &other)
        {
            //直接返回这个对象
            return *this;
        }
        delete[]str;
        int length = strlen(other.str) + 1;
        str = new char[length];
        strncpy(str, other.str, length);
        return *this;
    }
    //移动构造函数
    String(String&& other) noexcept :str(other.str)
    {
        cout << "String(string&& other)" << endl;
        other.str = nullptr;
    }

    //移动赋值语句
    String& operator=(String&& other) noexcept
    {
        cout << "String & operator=(String && other)" << endl;
        if (this == &other)
        {
            return *this;
        }

        delete[] str;
        str = other.str;
        other.str = nullptr;
        return *this;

    }

    // 打印字符串
    void print() const {
        if (str != nullptr) {
            cout << str << endl;
        }
        else {
            cout << "null" << endl;
        }
    }
};

int main()
{

    //  * @brief A class representing a sequence of characters.
    //  * 
    //  * The String class provides various functionalities to manipulate
    //  * and handle strings. It supports operations such as concatenation,
    //  * comparison, and substring extraction.

    const char* str = "Hello, World!";
    String s1; // 默认构造函数
    String s2(str); // 带参构造函数
    String s3(s2); // 拷贝构造函数
    String s4; // 默认构造函数
    s4 = s2; // 拷贝赋值运算符
    String s5(move(s2)); // 移动构造函数
    String s6; // 默认构造函数
    s6 = move(s5); // 移动赋值运算符

    cout << "s1: ";
    s1.print();
    cout << "s2: ";
    s2.print();
    cout << "s3: ";
    s3.print();
    cout << "s4: ";
    s4.print();
    cout << "s5: ";
    s5.print();
    cout << "s6: ";
    s6.print();
}
// String()
// String(const char *strsource)
// String(const String &other)
// String()
// String& operator=(cosnt String &other)
// String(string&& other)
// String()
// String & operator=(String && other)
// s1:
// s2: null
// s3: Hello, World!
// s4: Hello, World!
// s5: null
// s6: Hello, World!
// ~String()
// ~String()
// ~String()
// ~String()
// ~String()
// ~String()


 //类的定义
// class <类名>
// {
//     <访问控制符>:
//         <数据成员>;
//         <成员函数>;
//     public:
//         <数据成员>;
//         <成员函数>;
//     protected:
//         <数据成员>;
//         <成员函数>;
// };
//构造函数 constructor:为对象分配内存空间并初始化对象的数据成员。一般为公有public，或者私有private时只能在类中创建，限制创建该类对象的范围和方式。
#include<iostream>
using namespace std;
class A
{
private:
public:
    A();
    A(int i);
    ~A();
};

A::A(int i)
{
    cout<<"A(int i)"<<endl;
}
A::A()
{
    cout<<"A()"<<endl;
}
            
A::~A()
{
    cout<<"~A()"<<endl;
}

int main()
{
    A a;
    A b(1);
    A *p1=new A;
    A *p2=new A(2);
    A *p3=new A[2];
    delete p1;
    delete p2;
    delete []p3;
    p1=nullptr;
    p2=nullptr;
    p3=nullptr;

    return 0;
}
A()
A(int i)
A()
A(int i)
A()
A()
~A()
~A()
~A()
~A()
~A()
~A()
//创建动态对象时，一般只能用默认的构造函数进行初始化。如果用malloc创建动态对象，则系统不回去调用类的构造函数对其进行初始化。

//析构函数 destructor：在系统回收它所占用的内存空间之前，用delete释放对象的内存空间，同时调用析构函数对对象的数据成员进行清理。

//初始化表 member initializer list:在构造函数的函数体之前，用冒号分隔，后面跟着一个或多个初始化表项，每个初始化表项由一个数据成员名和一个初始化值构成。


//this 指针：当通过对象来调用类的成员函数时，系统会把相应对象的地址作为实参传给成员函数隐藏的形参this指针。
//void g(A *const this,int i){this->x=i;}
#include<iostream>
using namespace std;
class A;
void function(A* p);
class A
{
    
    public:
        int x;
        void f(int i)
        {
            cout<<"[f]this=\t"<<this<<endl;
            cout<<"[f]this->x=\t"<<this->x<<endl;
            x=i;
            cout<<"[f]this->x=\t"<<this->x<<endl;
        }
        void g(int i)
        {
            function(this);
            cout<<"[g]this=\t"<<this<<endl;
            cout<<"[g]this->x=\t"<<this->x<<endl;
            this->x=i;
            cout<<"[g]this->x=\t"<<this->x<<endl;
        }
};
void function(A* p)
{
    cout<<"functionp=\t"<<p<<endl;
    cout<<"function&p=\t"<<&p<<endl;
    cout<<"functionp->x=\t"<<p->x<<endl;
    cout<<"function&p->x=\t"<<&p->x<<endl;
}
int main()
{
    A a;
    cout<<"[main]&a=\t"<<&a<<endl;
    cout<<"[main]&a.x=\t"<<&a.x<<endl;
    a.f(1);
    cout<<"[main]a.x=\t"<<a.x<<endl;

    a.g(2);
    cout<<"[main]a.x=\t"<<a.x<<endl;

    A b;
    cout<<"[main]&b=\t"<<&b<<endl;
    cout<<"[main]&b.x=\t"<<&b.x<<endl;
    b.f(1);
    cout<<"[main]b.x=\t"<<b.x<<endl;

    b.g(2);
    cout<<"[main]b.x=\t"<<b.x<<endl;
    return 0;
}
// [main]&a=       0x7ffdd3c2ed80
// [main]&a.x=     0x7ffdd3c2ed80
// [f]this=        0x7ffdd3c2ed80
// [f]this->x=     -1585153728
// [f]this->x=     1
// [main]a.x=      1
// functionp=      0x7ffdd3c2ed80
// function&p=     0x7ffdd3c2ed48
// functionp->x=   1
// function&p->x=  0x7ffdd3c2ed80
// [g]this=        0x7ffdd3c2ed80
// [g]this->x=     1
// [g]this->x=     2
// [main]a.x=      2
// [main]&b=       0x7ffdd3c2ed84
// [main]&b.x=     0x7ffdd3c2ed84
// [f]this=        0x7ffdd3c2ed84
// [f]this->x=     32534
// [f]this->x=     1
// [main]b.x=      1
// functionp=      0x7ffdd3c2ed84
// function&p=     0x7ffdd3c2ed48
// functionp->x=   1
// function&p->x=  0x7ffdd3c2ed84
// [g]this=        0x7ffdd3c2ed84
// [g]this->x=     1
// [g]this->x=     2
// [main]b.x=      2

//动态变量：在程序运行时根据程序需要随时随地创建和撤销的变量。对于动态变量的访问需要通过指向动态变量的指针变量来进行
//需要注意的是，动态变量的内存空间分配在程序的堆中。
//1）C++提供了两种创建动态变量的机制new和malloc。
//new <类型>
//该操作在程序的堆区中创建一个类型由<类型>执行的动态变量，结果为该动态变量的地址。其类型为<类型> *。
//new操作创建一个int型的动态变量，该动态变量由指针p来指向；
//int *p=new int;//创建一个动态的整型变量，p指向该变量
//*p=1;//只能通过指针变量来访问该动态创建的类型
//用delete释放内存空间,撤销空间时，指针变量必须指向数组的第一个元素。

//2）malloc函数
//malloc函数的功能是在程序的堆区中分配一块指定大小的内存空间，其返回值为该内存空间的首地址。malloc函数的原型为：
//void *malloc(size_t size);
//该函数的参数size指定了需要分配的内存空间的大小，单位为字节。malloc函数返回的是void *类型的指针，需要强制类型转换为需要的类型。
//另外用free()函数释放内存空间
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    int n;
    while (1)
    {
        cout<<"please input n:";
        cin>>n;
        cout<<"n="<<n<<endl;
        /////////////////////////////////////////[NEW]///////////////////////////////////////////////////
        int *p=new int[n];
        bzero(p,n*sizeof(int));
        //memset函数的功能是将某一块内存中的内容全部设置为某一个字符，它是对较大的结构体或数组进行清零操作的一种最快方法。
        for(int i=0;i<n;i++)
        {
            p[i]=i;
        }
        for(int i=0;i<n;i++)
        {
            cout<<"p["<<i<<"]="<<p[i]<<endl;
        }
        delete []p;  
        p=nullptr;
        cout<<"delete p"<<endl; 

        int (*q)[3];
        q=new int[n][3];
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<3;j++)
            {
                q[i][j]=i+j;
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<3;j++)
            {
                cout<<"q["<<i<<"]["<<j<<"]="<<q[i][j]<<endl;
            }
        }
        delete []q;
        cout<<"delete q"<<endl;
        q=nullptr;

        /////////////////////////////////////////[MALLOC]///////////////////////////////////////////////////
        int *pm1=(int *)malloc(sizeof(int));
        *pm1=100;
        cout<<"*pm1:"<<*pm1<<endl;
        free(pm1);

        int *pm2=(int *)malloc(n*sizeof(int));
        for(int i=0;i<n;i++)
        {
            pm2[i]=i;
        }
        for(auto i=0;i<n;i++)
        {
            cout<<"pm2["<<i<<"]="<<pm2[i]<<endl;
        }
        free(pm2);
        pm2=nullptr;
        typedef int A[4];
        int (*qm1)[4]=(A*)malloc(sizeof(int)*n*4);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<4;j++)
            {
                qm1[i][j]=i+j;
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<4;j++)
            {
                cout<<"qm1["<<i<<"]["<<j<<"]="<<qm1[i][j]<<endl;
            }
        }
        free(qm1);
        qm1=nullptr;

        cout<<"delete qm1"<<endl;
    }

    return 0;
}


//指针
#include<iostream>
using namespace std;
int main()
{
    int *p,x;
    x=1;
    cout<<"x= :"<<x<<" x address:"<<&x<<endl;
    p=&x;
    cout<<"p=:"<<p<<" *p=:"<<*p<<endl;
    *p=2;
    cout<<"p=:"<<p<<" *p=:"<<*p<<endl;
    cout<<"x=:"<<x<<" &x="<<&x<<endl;
    return 0;
    
}
// maverick@localhost:/project/programming-with-c$ ./test
// x= :1 x address:0x7fffc80c107c
// p=:0x7fffc80c107c *p=:1
// p=:0x7fffc80c107c *p=:2
// x=:2 &x=0x7fffc80c107c

#include<iostream>
//类的构造函数、析构函数与赋值函数
//C++每个类只有一个析构函数和一个赋值函数，但可以有多个构造函数，
//包含一个拷贝构造函数，其他的称为普通构造函数/
//
//C++默认四个缺省的函数
//A(void) //缺省的无参构造函数
//A(const A& a)//缺省拷贝构造函数
//~A(void) //缺省的析构函数
//A& operator=(const A& a);//缺省的赋值函数
//
//1)如果使用缺省的无参构造函数，和缺省的析构函数，等于放弃了自主初始化和清除的机会。
//2）缺省的拷贝构造函数和缺省的赋值函数，采用位拷贝，而不是值拷贝的方式实现，
//倘若类中含有指针变量，这两个函数注定出错。
using namespace std;

class Deep
{
public:
	int* data;
public:
	Deep(int val)
	{
		cout << "construct function" << endl;
		data = new int(val);
	}
	//显示实现拷贝构造函数
	Deep(const Deep & source)
	{
		cout << "copyconstruct  function" << endl;
		data = new int(*source.data);
	}
	int getdata() const
	{
		return *data;
	}
	~Deep(){delete data;
	}
};

//类默认拷贝构造函数，默认赋值函数
//均为浅拷贝
class Shallow
{
public:
	int* data;

public:

	//构造函数
	Shallow(int val)
	{
		data = new int(val);
	}
	//默认的拷贝构造函数是位拷贝
};


//消息的动态绑定

int main()
{
	Shallow obj1(100);
	cout << *obj1.data << endl;
	Shallow obj2 = obj1;

	cout << *obj1.data <<"\t" << *obj2.data << endl;
	*(obj2.data) = 300;
	cout << *obj1.data << "\t" << *obj2.data << endl;


	Deep deep1(100);
	cout << " *deep1.data:" << *deep1.data << endl;
	Deep deep2 = deep1;
	cout << "*deep2.data:" << *deep2.data << "\t " << "*deep1.data: " << *deep1.data << endl;
	*deep2.data = 900;
	cout << " *deep2.data:" << *deep2.data << "\t " << "*deep1.data: " << *deep1.data << endl;

	cout<<"deep2.getdaa: "<<deep2.getdata()<< "data1.getdata() "<<deep1.getdata();
	return 0;
}
